home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
626-637
/
disk_633
/
galer
/
source
/
port.asm
< prev
next >
Wrap
Assembly Source File
|
1992-05-06
|
14KB
|
571 lines
*
* Routinen zur Steuerung des GAL-Brenners
*
* assemblieren: as -n -c -d port.asm
*
GAL16V8 EQU 1 ; GAL-Typ
GAL20V8 EQU 2
IC1 EQU 3 ; IC-Nummer
IC3 EQU 0
IC4 EQU 1
IC5 EQU 2
IC6 EQU 0
IC7 EQU 1
ON EQU 1 ; für LED-Steuerung
OFF EQU 0
PROG EQU 1 ; Edit-Mode für GAL
VERIFY EQU 0
ciaapb EQU $BFE101
ciabpa EQU $BFD000
ciaapbd EQU $BFE301
public _InitGALer ; GALer initialisieren
public _WriteByte ; Byte in Schiebereg. schreiben
public _ReadByte ; Byte aus Schiebereg. lesen
public _SetGAL ; GAL-Type festlegen
public _VeditOn ; Edit-Spannung aufbauen
public _VeditOff ; Edit-Spannung abschalten
public _LED ; LED ansteuern
public _EnableVcc ; Vcc anlegen
public _DisableVcc ; Vcc abschalten
public _EnableVEdit ; Edit-Spannung anlegen
public _DisableVEdit ; Edit-Spannung abschalten
public _EnableOutput ; Ausgangs-Treiber aktivieren
public _DisableOutput ; Ausgangs-Treiber deaktiviern
public _SetRow ; Adresse an RAG0-RAG5 anlegen
public _SDIn ; Lege ein Bit an SDIn-Eingang
public _SDOut ; Bit vom SDOut-Ausgang holen
public _Clock ; Clock-Impuls an SCLK-Eingang
public _STRImpuls ; STR-Impuls erzeugen
public _EditMode ; setzt Bits für Edit-Mode
XDEF _GALType
XDEF _outIC1
XDEF _outIC3
XDEF _outIC4
XDEF _outIC5
XREF _LVODelay
XREF _DOSBase
XREF _WaitForTimer
cseg
* GALer initialisieren: Datenleitung vom Par.-Port auf Ausgang, alle
* Ausgänge von IC1 auf LOW (kein OutputEnable für IC3,4,5 aber Register-
* Inhalt von IC3,4,5 auf LOW stellen)
* Parameter: keine
_InitGALer:
move.b #$ff,ciaapbd ; Datenleitungen auf Ausgang schalten
or.b #%00001000,ciaapb ; PD3=H: Adressdecoder deaktivieren!
and.b #%00001000,ciaapb ; alle anderen Datenleitungen auf LOW
; ACHTUNG!!!: PD3 darf nur auf LOW-Pegel gehen
; (Adressdecoder aktiviert werden), wenn durch PD0 und
; PD1 das IC das angesprochen werden soll, bereits
; selektiert ist. Ansonsten bekommt ein IC einen Takt-
; impuls und beim nächsten Strobe liegen dann die
; falschen Daten an.
move.w #IC1,-(sp)
clr.w -(sp)
bsr _WriteByte ; Ausgänge von IC1 auf LOW
addq.l #4,sp ; Stack korrigieren
move.w #IC3,-(sp)
clr.w -(sp)
bsr _WriteByte ; Ausgänge von IC3 auf LOW
addq.l #4,sp ; Stack korrigieren
move.w #IC4,-(sp)
clr.w -(sp)
bsr _WriteByte ; Ausgänge von IC4 auf LOW
addq.l #4,sp ; Stack korrigieren
move.w #IC5,-(sp)
clr.w -(sp)
bsr _WriteByte ; Ausgänge von IC5 auf LOW
addq.l #4,sp ; Stack korrigieren
rts
* SetGAL:
* Setzte GAL-Type fest (GAL16V8, GAL20V8)
* Aufruf: SetGAL(type);
*
_SetGAL:
move.w 4(sp),_GALType
rts
* VeditOn:
* schaltet den Sperrwandler an (IC9); siehe auch VeditOff
* Auruf: VeditOn();
_VeditOn:
move.w #IC1,-(sp)
or.w #%00001,_outIC1 ; Q1 von IC1 auf HIGH => VeditOn
move.w _outIC1,-(sp)
bsr _WriteByte ; IC1 setzen
addq.l #4,sp ; Stack korrigieren
rts
* VeditOff:
* schaltet den Sperrwandler aus (IC9); siehe auch VeditOn
* Auruf: VeditOff();
_VeditOff:
move.w #IC1,-(sp)
and.w #%11111110,_outIC1 ; Q1 von IC1 auf LOW => VeditOff
move.w _outIC1,-(sp)
bsr _WriteByte ; IC1 setzen
addq.l #4,sp ; Stack korrigieren
rts
* EnableVEdit:
* schaltet die Edit-Spannung (+16.5V) auf Pin 2 oder Pin 4 vom Textool
* (abhänging vom eingestellten GAL-Typ)
* Aufruf: EnableVEdit();
_EnableVEdit:
move.w #IC1,-(sp) ; IC1 einstellen
cmp.w #GAL16V8,_GALType ; 16V8 eingestellt?
bne.s 1$ ; nein, dann wird 20V8 angenommen!
moveq #%00000100,d0 ; Q3 von IC1 auf HIGH
bra.s 2$
1$ moveq #%00000010,d0 ; Q2 von IC1 auf HIGH
2$ or.w d0,_outIC1
move.w _outIC1,-(sp)
bsr _WriteByte
addq.l #4,sp
rts
* DisableVEdit:
* schaltet die Edit-Spannung (+16.5V) an Pin 2 oder Pin 4 aus
* (abhänging vom eingestellten GAL-Typ)
* Aufruf: DisableVEdit();
_DisableVEdit:
move.w #IC1,-(sp) ; IC1 einstellen
cmp.w #GAL16V8,_GALType ; 16V8 eingestellt?
bne.s 1$ ; nein, dann wird 20V8 angenommen!
move.w #%11111011,d0 ; Q3 von IC1 auf LOW
bra.s 2$
1$ move.w #%11111101,d0 ; Q2 von IC1 auf low
2$ and.w d0,_outIC1
move.w _outIC1,-(sp)
bsr _WriteByte
addq.l #4,sp
rts
* LED:
* schaltet die LED aus bzw. an
* Aufruf: LED(ON/OFF);
_LED:
cmp.w #ON,4(sp)
bne.s 2$
or.w #%01000000,_outIC1
bra.s 1$
2$ and.w #%10111111,_outIC1
1$ move.w #IC1,-(sp)
move.w _outIC1,-(sp)
bsr _WriteByte ; IC1 setzen
addq.l #4,sp ; Stack korrigieren
rts
* EnableVcc:
* schaltet die Spannungsversorgung ein; siehe auch DisableVcc
* bei GAL16V8: Pin22 vom Textool-Sockel
* bei GAL20V8: Pin24 vom Textool-Sockel
* Aufruf: EnableVcc();
_EnableVcc:
move.w #IC1,-(sp) ; IC1 selektieren
cmp.w #GAL16V8,_GALType ; 16V8 eingestellt?
bne.s 1$ ; nein, dann wird 20V8 angenommen!!!
moveq #%00011000,d0 ; Q4,5 von IC1 auf HIGH=>+5V an Pin22
bra.s 2$
1$ moveq #%00010000,d0 ; Q5 auf HIGH => +5V an Pin 24
2$ or.w d0,_outIC1
move.w _outIC1,-(sp)
bsr _WriteByte ; IC1 setzen
addq.l #4,sp ; Stack korrigieren
rts
* DisableVcc:
* schaltet die Spannungsversorgung aus; siehe auch EnableVcc
* bei GAL16V8: Pin22 vom Textool-Sockel
* bei GAL20V8: Pin24 vom Textool-Sockel
* Aufruf: DisableVcc();
_DisableVcc:
move.w #IC1,-(sp) ; IC1 selektieren
cmp.w #GAL16V8,_GALType ; 16V8 eingestellt?
bne.s 1$ ; nein, dann wird 20V8 angenommen!!!
move.w #%11100111,d0 ; Q4,5 von IC1 auf LOW
bra.s 2$
1$ move.w #%11101111,d0 ; Q5 auf HIGH => +5V an Pin 24
2$ and.w d0,_outIC1
move.w _outIC1,-(sp)
bsr _WriteByte ; IC1 setzen
addq.l #4,sp ; Stack korrigieren
rts
* EnableOutput:
* OutputEnable-Eingang (OE) von IC3, IC4, IC5 auf HIGH
* Aufruf: EnableOutput();
_EnableOutput:
move.w #IC1,-(sp)
or.w #%00100000,_outIC1
move.w _outIC1,-(sp)
bsr _WriteByte
addq.l #4,sp
rts
* DisableOutput:
* OutputEnable-Eingang (OE) von IC3, IC4, IC5 auf LOW
* Aufruf: DisableOutput();
_DisableOutput:
move.w #IC1,-(sp)
and.w #%11011111,_outIC1
move.w _outIC1,-(sp)
bsr _WriteByte
addq.l #4,sp
rts
* ReadByte:
* lese ein Byte aus dem IC "ICx", wobei ICx=IC6 (nur ein Bit) oder IC7 ist
* Aufruf: byte=ReadByte(IC);
* PD3 ist bereits HIGH (muß es auch!, siehe _InitGAL und Beschreibung zu PD3)
_ReadByte:
clr.w d0
cmp.w #IC6,4(sp) ; IC6 angesprochen?
bne.s IC7$ ; nein, dann IC7$
or.b #%00000001,ciaapb ; PD0 auf HIGH=>HIGH am Clk vom IC7
; PD0 auf HIGH setzen=>IC6a selektiert
move.b ciabpa,d0
not.b d0 ; invertieren
and.b #%00000001,d0 ; BUSY-Bit ausmaskieren
bra.s ready$ ; Pin22 (über IC6) ist ausgelesen
IC7$
and.b #%11111110,ciaapb ; PD3 ist HIGH=>Lesen möglich
nop
or.b #%00000100,ciaapb ; PD2 (Strobe) auf HIGH-> Daten werden
and.b #%11111011,ciaapb ; vom Eingangsreg. in das Schiebereg.
; übernommen. Dann PD2 wieder auf LOW.
; PD3 ist auf HIGH=>Lesen ist möglich
moveq #7,d2 ; Schleifenzähler
l$ rol.b #1,d0
move.b ciabpa,d1 ; BUSY-Bit holen
and.b #%00000001,d1 ; BUSY-Bit ausmaskieren
or.b d1,d0 ; BUSY-Bit in D0 eintragen
and.b #%11111110,ciaapb ; PD0 auf LOW=>LOW am Clk-Eingang (IC7)
or.b #%00000001,ciaapb ; PD0 auf HIGH=>HIGH am Clk-Eingang
; ==> nächstes Bit steht am Ausgang
nop
nop
and.b #%11111110,ciaapb ; PD0 auf LOW=>IC6b ist selektiert (=>lesen möglich)
dbf d2,l$ ; 8 Bits auslesen
not.b d0 ; invertieren
ready$ rts ; D0=Rückgabewert (gelesenes Byte)
* WriteByte:
* schreibt das Byte "byte" in das IC "IC", wobei IC=IC1, IC3, IC4 oder IC5
* sein kann
* zuerst wird das MSB übertragen!!!
* Aufruf: WriteByte(byte,IC)
_WriteByte:
movem.l d0-d3,savereg ; Register retten
move.w 4(sp),d0 ; Datenbyte nach D0
move.w 6(sp),d1 ; IC nach D1
; geschriebenes Byte mitprotokolieren
cmp.w #IC1,d1
bne.s 1$
move.w d0,_outIC1
bra.s cont$
1$ cmp.w #IC3,d1
bne.s 2$
move.w d0,_outIC3
bra.s cont$
2$ cmp.w #IC4,d1
bne.s 3$
move.w d0,_outIC4
bra.s cont$
3$ move.w d0,_outIC5
cont$
and.b #%11111100,ciaapb ; PD0 und PD1 setzen (IC aus-
or.b d1,ciaapb ; wählen)
and.b #%11110111,ciaapb ; Adressdecoder aktivieren
moveq #7,d3 ; Schleifenzähler
ror.b #3,d0 ; MSB nach D4 (Datenleitung)
loop$ move.b d0,d2 ; Datenbyte sichern
and.b #%00010000,d2 ; Datenbit ausmaskieren
or.b d2,ciaapb ; Datenbit (PD4) vom Par.-Port setzen
or.b #%00001000,ciaapb ; Clock-Impuls durch PD3 geben
and.b #%11110111,ciaapb ; LOW-HIGH Übergang
and.b #%11101111,ciaapb ; Datenbit (PD4) auf LOW
rol.b #1,d0 ; nächstniedrigeres Bit senden
dbf d3,loop$
or.b #%00001000,ciaapb ; Adressdecoder wieder deaktivieren!!!
; (sehr WICHTIG, siehe _InitGAL:)
or.b #%00000100,ciaapb ; PD2 (Strobe) auf HIGH-> Daten werden
and.b #%11111011,ciaapb ; vom Schieberegister in das Datenreg.
; übernommen. Dann PD2 wieder auf LOW.
movem.l savereg,d0-d3
rts
* SetRow:
* Adresse an RAG0-RAG5 anlegen
* Aufruf: SetRow(row);
* row: zu adressierende Zeile (0-63)
_SetRow:
; RAG5 setzen (Pin bei 16 und 20V8 gleich)
move.w 4(sp),d0 ; row holen
and.w #$fe,_outIC5 ; Bit0(=RAG5) löschen
asr.b #5,d0 ; Bit0 von D0=RAG5
or.w d0,_outIC5 ; RAG5=Bit von D0=> RAG5 gesetzt
cmp.w #GAL16V8,_GALType ; GAL16V8?
bne.s GAL20V8$ ; nein, dann GAL20V8 annehmen
GAL16V8$ ; RAG0 setzen
move.w 4(sp),d0 ; row holen
and.w #$ef,_outIC3 ; Bit4(=RAG0) löschen
and.w #1,d0 ; Bit0 von "row" ausmaskieren
asl.b #4,d0
or.w d0,_outIC3 ; Bit4(=RAG0) setzen
; RAG1-RAG4 setzen
move.w 4(sp),d0 ; row holen
and.w #$0f,_outIC4 ; Bit4-7(=RAG1-RAG4) löschen
and.w #%00011110,d0 ; Bit1-4 von "row" ausmaskieren
asl.w #3,d0 ; an Bit4-7 schieben
or.w d0,_outIC4 ; RAG1-RAG4 setzen
bra.s write$
GAL20V8$ ; RAG0 für GAL20V8 setzen
move.w 4(sp),d0 ; row holen
and.w #%11011111,_outIC3 ; Bit5(=RAG0) löschen
and.w #1,d0 ; Bit0 von "row" ausmaskieren
asl.b #5,d0
or.w d0,_outIC3 ; Bit5(=RAG0) setzen
; RAG4 setzen
move.w 4(sp),d0 ; row holen
and.w #%01111111,_outIC4 ; Bit7(=RAG4) löschen
and.w #%00010000,d0 ; Bit4 von "row" ausmaskieren
asl.w #3,d0
or.w d0,_outIC4 ; Bit7(=RAG4) setzen
; RAG1-RAG3 setzen
move.w 4(sp),d0 ; row holen
and.w #%11100011,_outIC4 ; Bit2-4(=RAG1-RAG3) löschen
and.w #%00001110,d0 ; Bit1-3 aus "row" ausmaskieren
asl.w #1,d0
or.w d0,_outIC4 ; RAG1-RAG3 setzen
write$ ; errechnete Werte in ICs schreiben
move.w #IC3,-(sp)
move.w _outIC3,-(sp)
bsr _WriteByte
addq.l #4,sp
move.w #IC4,-(sp)
move.w _outIC4,-(sp)
bsr _WriteByte
addq.l #4,sp
move.w #IC5,-(sp)
move.w _outIC5,-(sp)
bsr _WriteByte
addq.l #4,sp
rts
* SDIn:
* lege ein Bit an den SDIn-Eingang (Pin 11 vom Textool-Sockel)
* Aufruf: SDIn(bit); bit: 0=LOW; 1=HIGH
_SDIn:
move.w 4(sp),d0 ; Bit holen
asl.b #2,d0 ; an die richtige Stelle schieben
and.w #%11111011,_outIC5 ; SDIn-Bit löschen
or.w d0,_outIC5 ; Bit auf LOW oder HIGH setzen
move.w #IC5,-(sp)
move.w _outIC5,-(sp)
bsr _WriteByte
addq.l #4,sp
rts
* SDOut:
* ein Bit aus dem SDOut-Ausgang lesen
* Pin 14 (GAL16V8), Pin 15 (GAL20V8) am Textool-Sockel
* Aufruf: bit=SDOut();
* bit: 0: SDOut-Pin ist LOW; 1: SDOut-Pin ist HIGH
_SDOut:
move.w #IC7,-(sp) ; ein Byte aus IC7 holen
bsr _ReadByte ; Bit0=Pin14, Bit1=Pin15
addq.l #2,sp
cmp.w #GAL16V8,_GALType ; GAL16V8 eingestellt?
bne.s 1$ ; nein, dann GAL20V8
and.w #1,d0 ; Bit0 ausmaskieren
bra.s 2$ ; D0=Bit
; GAL20V8
1$ asr.w #1,d0 ; SDOut-Bit an Bit-Pos. 0
and.w #1,d0
2$ rts
* Clock:
* erzeuge Clock-Impuls (Low-High-Low-Übergang) am SCLK-Eingang (Pin 10
* vom Textool-Sockel
* Aufruf: Clock();
_Clock:
or.w #%00000010,_outIC5 ; SCLK-Bit auf HIGH
move.w #IC5,-(sp)
move.w _outIC5,-(sp)
bsr _WriteByte
addq.w #4,sp
nop ; etwas warten
nop
nop
nop
and.w #%11111101,_outIC5 ; SCLK-Bit auf LOW
move.w #IC5,-(sp)
move.w _outIC5,-(sp)
bsr _WriteByte
addq.w #4,sp
rts
* STRImpuls:
* setzt /STR-Eingang (Pin 13 am Textool-Socker) für 10 ms auf LOW
* Aufruf: STRImpuls();
_STRImpuls:
movem.l d0-d7/a0-a6,savereg ; Register retten
and.w #%11110111,_outIC5 ; STR-Pin auf LOW
move.w #IC5,-(sp)
move.w _outIC5,-(sp)
bsr _WriteByte
addq.l #4,sp
move.l #10000,-(sp) ; 10000us=10ms
clr.l -(sp) ; 0 Sekunden warten
jsr _WaitForTimer ; 10 ms Low-Impuls
addq.l #8,sp ; Stack korrigieren
or.w #%00001000,_outIC5 ; STR-Pin wieder auf HIGH
move.w #IC5,-(sp)
move.w _outIC5,-(sp)
bsr _WriteByte
addq.l #4,sp
movem.l savereg,d0-d7/a0-a6 ; Registerinthalte zurückholen
rts
* Edit-Mode:
* schaltet das GAL in den Edit-Mode
* Aufruf: EditMode(mode);
* mode: PROG - GAL programmieren
* VERIFY - GAL lesen
_EditMode:
movem.l d0-d7/a0-a6,savereg ; Register sichern
move.w 4(sp),d0 ; "mode" holen
cmp.w #GAL16V8,_GALType ; GAL16V8?
bne.s 1$ ; nein, dann 1$
move.w #IC3,-(sp) ; IC3 setzen
move.w #%00000000,d1
asl.b #5,d0 ; Mode-Bit zu Bit 5 schieben
or.w d0,d1 ; P,/V-Bit setzen
move.w d1,-(sp)
bsr _WriteByte
addq.l #4,sp
move.w #IC4,-(sp)
move.w #%00000000,-(sp) ; IC4 initialisieren
bsr _WriteByte
addq.l #4,sp
move.w #IC5,-(sp)
move.w #%00011000,-(sp) ; IC5 initialisieren
bsr _WriteByte
addq.l #4,sp
bra.s 2$
1$ ; GAL20V8
move.w #IC3,-(sp) ; IC3 setzen
move.w #%00000000,d1
asl.b #6,d0 ; Mode-Bit zu Bit 6 schieben
or.w d0,d1 ; P,/V-Bit setzen
move.w d1,-(sp)
bsr _WriteByte
addq.l #4,sp
move.w #IC4,-(sp)
move.w #%00000000,-(sp) ; IC4 initialisieren
bsr _WriteByte
addq.l #4,sp
move.w #IC5,-(sp)
move.w #%00101000,-(sp) ; IC5 initialisieren
bsr _WriteByte
addq.l #4,sp
2$
bsr _VeditOn ; Edit-Spannung aufbauen
bsr _EnableOutput ; Bits anlegen
bsr _EnableVcc ; Vcc anlegen
move.l _DOSBase,a6
moveq #20,d1 ; Prellzeit der Relais überbrücken
jsr _LVODelay(a6)
bsr _EnableVEdit ; Edit-Spannung anlegen
; GAL befindet sich jetzt im Edit-Mode
movem.l savereg,d0-d7/a0-a6 ; Registerinhalte zurückholen
rts
dseg
; Zwischenspeicher, um Register zu retten ohne den Stack zu benützen
savereg: ds.l 15 ; 8 Datenregister, 7 Adressregister
_outIC1: dc.w 0
_outIC3: dc.w 0
_outIC4: dc.w 0
_outIC5: dc.w 0
_GALType: dc.w 0
END